﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO.Compression;
using System.Runtime.Serialization;
using System.Xml;

namespace BeanboxSoftware.BeanMap
{
  namespace Internal
  {
    static class DataContractSerializerUtility
    {
      public static string Serialize(object obj)
      {
        var serializer = new DataContractSerializer(obj.GetType());
        using (var writer = new StringWriter())
        using (var stm = new XmlTextWriter(writer))
        {
          serializer.WriteObject(stm, obj);
          return writer.ToString();
        }
      }

      public static object Deserialize(string serialized, Type type)
      {
        var serializer = new DataContractSerializer(type);
        using (var reader = new StringReader(serialized))
        {
          using (var stm = new XmlTextReader(reader))
          {
            return serializer.ReadObject(stm);
          }
        }
      }

      public static object ReadObject(System.Xml.XmlReader reader, Type type)
      {
        reader.Read();
        string cdata = reader.Value; //from cdata
        object raw = Deserialize(cdata, type);

        return raw;
      }

      public static void WriteObject(System.Xml.XmlWriter writer, object obj)
      {
        string xml = Serialize(obj);
        writer.WriteCData(xml);
      }
    }

    public abstract partial class MapBase<TGen, TValue, TPrimaryKey, TPrimaryValue> : DictionaryCommonBase<TPrimaryKey, TPrimaryValue>, IXmlSerializable
    {
      System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
      {
        return null;
      }

      void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
      {
        var raw = DataContractSerializerUtility.ReadObject(reader, typeof(MapBaseSerialData));
        _storage = raw as MapBaseSerialData;
        
        ReadStorage();
      }

      void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
      {
        WriteStorage();
        DataContractSerializerUtility.WriteObject(writer, _storage);
      }
    }
  }
}
